home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_arg.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  9.8 KB  |  356 lines

  1. //
  2. // "$Id: Fl_arg.cxx,v 1.5 1999/01/07 19:17:31 mike Exp $"
  3. //
  4. // Optional argument initialization code for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. // OPTIONAL initialization code for a program using fltk.
  27. // You do not need to call this!  Feel free to make up your own switches.
  28.  
  29. #include <FL/Fl.H>
  30. #include <FL/x.H>
  31. #include <FL/Fl_Window.H>
  32. #include <FL/filename.H>
  33. #include <FL/fl_draw.H>
  34. #include <ctype.h>
  35. #include <string.h>
  36.  
  37. #ifdef WIN32
  38. int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
  39. #define NoValue        0x0000
  40. #define XValue      0x0001
  41. #define YValue        0x0002
  42. #define WidthValue      0x0004
  43. #define HeightValue      0x0008
  44. #define AllValues     0x000F
  45. #define XNegative     0x0010
  46. #define YNegative     0x0020
  47. #endif
  48.  
  49. static int match(const char *a, const char *match, int atleast = 1) {
  50.   const char *b = match;
  51.   while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
  52.   return !*a && b >= match+atleast;
  53. }
  54.  
  55. // flags set by previously parsed arguments:
  56. extern char fl_show_iconic; // in Fl_x.C
  57. static char arg_called;
  58. static char return_i;
  59. static const char *name;
  60. static const char *geometry;
  61. static const char *title;
  62. // these are in Fl_get_system_colors and are set by the switches:
  63. extern const char *fl_fg;
  64. extern const char *fl_bg;
  65. extern const char *fl_bg2;
  66.  
  67. // consume a switch from argv.  Returns number of words eaten, 0 on error:
  68. int Fl::arg(int argc, char **argv, int &i) {
  69.   arg_called = 1;
  70.   const char *s = argv[i];
  71.  
  72.   if (!s) {i++; return 1;}    // something removed by calling program?
  73.  
  74.   // a word that does not start with '-', or a word after a '--', or
  75.   // the word '-' by itself all start the "non-switch arguments" to
  76.   // a program.  Return 0 to indicate that we don't understand the
  77.   // word, but set a flag (return_i) so that args() will return at
  78.   // that point:
  79.   if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;}
  80.   s++; // point after the dash
  81.  
  82.   if (match(s, "iconic")) {
  83.     fl_show_iconic = 1;
  84.     i++;
  85.     return 1;
  86.   }
  87.  
  88.   const char *v = argv[i+1];
  89.   if (i >= argc-1 || !v)
  90.     return 0;    // all the rest need an argument, so if missing it is an error
  91.  
  92.   if (match(s, "geometry")) {
  93.  
  94.     int flags, gx, gy; unsigned int gw, gh;
  95.     flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
  96.     if (!flags) return 0;
  97.     geometry = v;
  98.  
  99. #ifndef WIN32
  100.   } else if (match(s, "display")) {
  101.     Fl::display(v);
  102. #endif
  103.  
  104.   } else if (match(s, "title")) {
  105.     title = v;
  106.  
  107.   } else if (match(s, "name")) {
  108.     name = v;
  109.  
  110.   } else if (match(s, "bg2", 3) || match(s, "background2", 11)) {
  111.     fl_bg2 = v;
  112.  
  113.   } else if (match(s, "bg") || match(s, "background")) {
  114.     fl_bg = v;
  115.  
  116.   } else if (match(s, "fg") || match(s, "foreground")) {
  117.     fl_fg = v;
  118.  
  119.   } else return 0; // unrecognized
  120.  
  121.   i += 2;
  122.   return 2;
  123. }
  124.  
  125. // consume all switches from argv.  Returns number of words eaten.
  126. // Returns zero on error.  'i' will either point at first word that
  127. // does not start with '-', at the error word, or after a '--', or at
  128. // argc.  If your program does not take any word arguments you can
  129. // report an error if i < argc.
  130.  
  131. int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) {
  132.   arg_called = 1;
  133.   i = 1; // skip argv[0]
  134.   while (i < argc) {
  135.     if (cb && cb(argc,argv,i)) continue;
  136.     if (!arg(argc,argv,i)) return return_i ? i : 0;
  137.   }
  138.   return i;
  139. }
  140.  
  141.  
  142. // show a main window, use any parsed arguments
  143. void Fl_Window::show(int argc, char **argv) {
  144.   if (!arg_called) Fl::args(argc,argv);
  145.  
  146.   // set colors first, so background_pixel is correct:
  147.   static char beenhere;
  148.   if (!beenhere) {
  149.     beenhere = 1;
  150.     Fl::get_system_colors(); // opens display!  May call Fl::fatal()
  151.     if (geometry) {
  152.       int flags = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
  153.       flags = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
  154.       if (flags & XNegative) gx = Fl::w()-w()+gx;
  155.       if (flags & YNegative) gy = Fl::h()-h()+gy;
  156.       //  int mw,mh; minsize(mw,mh);
  157.       //  if (mw > gw) gw = mw;
  158.       //  if (mh > gh) gh = mh;
  159.       Fl_Widget *r = resizable();
  160.       if (!r) resizable(this);
  161.       // for WIN32 we assumme window is not mapped yet:
  162.       if (flags & (XValue | YValue))
  163.     x(-1), resize(gx,gy,gw,gh);
  164.       else
  165.     size(gw,gh);
  166.       resizable(r);
  167.     }
  168.   }
  169.  
  170.   if (name) {xclass(name); name = 0;}
  171.   else if (!xclass()) xclass(filename_name(argv[0]));
  172.   if (title) {label(title); title = 0;}
  173.   else if (!label()) label(xclass());
  174.   show();
  175.  
  176. #ifndef WIN32
  177.   // set the command string, used by state-saving window managers:
  178.   int i;
  179.   int n=0; for (i=0; i<argc; i++) n += strlen(argv[i])+1;
  180. #ifdef __GNUC__
  181.   char buffer[n];
  182. #else
  183.   char *buffer = new char[n];
  184. #endif
  185.   char *p = buffer;
  186.   for (i=0; i<argc; i++) for (const char *q = argv[i]; (*p++ = *q++););
  187.   XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
  188.           (unsigned char *)buffer, p-buffer-1);
  189. #ifndef __GNUC__
  190.   delete[] buffer;
  191. #endif
  192. #endif
  193.  
  194. }
  195.  
  196. // Calls useful for simple demo programs, with automatic help message:
  197.  
  198. static const char * const helpmsg =
  199. "options are:\n"
  200. " -d[isplay] host:n.n\n"
  201. " -g[eometry] WxH+X+Y\n"
  202. " -t[itle] windowtitle\n"
  203. " -n[ame] classname\n"
  204. " -i[conic]\n"
  205. " -fg color\n"
  206. " -bg color\n"
  207. " -bg2 color";
  208.  
  209. const char * const Fl::help = helpmsg+13;
  210.  
  211. void Fl::args(int argc, char **argv) {
  212.   int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
  213. }
  214.  
  215. #ifdef WIN32
  216.  
  217. /* the following function was stolen from the X sources as indicated. */
  218.  
  219. /* Copyright     Massachusetts Institute of Technology  1985, 1986, 1987 */
  220. /* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
  221.  
  222. /*
  223. Permission to use, copy, modify, distribute, and sell this software and its
  224. documentation for any purpose is hereby granted without fee, provided that
  225. the above copyright notice appear in all copies and that both that
  226. copyright notice and this permission notice appear in supporting
  227. documentation, and that the name of M.I.T. not be used in advertising or
  228. publicity pertaining to distribution of the software without specific,
  229. written prior permission.  M.I.T. makes no representations about the
  230. suitability of this software for any purpose.  It is provided "as is"
  231. without express or implied warranty.
  232. */
  233.  
  234. /*
  235.  *    XParseGeometry parses strings of the form
  236.  *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
  237.  *   width, height, xoffset, and yoffset are unsigned integers.
  238.  *   Example:  "=80x24+300-49"
  239.  *   The equal sign is optional.
  240.  *   It returns a bitmask that indicates which of the four values
  241.  *   were actually found in the string.  For each value found,
  242.  *   the corresponding argument is updated;  for each value
  243.  *   not found, the corresponding argument is left unchanged. 
  244.  */
  245.  
  246. static int ReadInteger(char* string, char** NextString)
  247. {
  248.   register int Result = 0;
  249.   int Sign = 1;
  250.     
  251.   if (*string == '+')
  252.     string++;
  253.   else if (*string == '-') {
  254.     string++;
  255.     Sign = -1;
  256.   }
  257.   for (; (*string >= '0') && (*string <= '9'); string++) {
  258.     Result = (Result * 10) + (*string - '0');
  259.   }
  260.   *NextString = string;
  261.   if (Sign >= 0)
  262.     return (Result);
  263.   else
  264.     return (-Result);
  265. }
  266.  
  267. int XParseGeometry(const char* string, int* x, int* y,
  268.            unsigned int* width, unsigned int* height)
  269. {
  270.   int mask = NoValue;
  271.   register char *strind;
  272.   unsigned int tempWidth, tempHeight;
  273.   int tempX, tempY;
  274.   char *nextCharacter;
  275.  
  276.   if ( (string == NULL) || (*string == '\0')) return(mask);
  277.   if (*string == '=')
  278.     string++;  /* ignore possible '=' at beg of geometry spec */
  279.  
  280.   strind = (char *)string;
  281.   if (*strind != '+' && *strind != '-' && *strind != 'x') {
  282.     tempWidth = ReadInteger(strind, &nextCharacter);
  283.     if (strind == nextCharacter) 
  284.       return (0);
  285.     strind = nextCharacter;
  286.     mask |= WidthValue;
  287.   }
  288.  
  289.   if (*strind == 'x' || *strind == 'X') {    
  290.     strind++;
  291.     tempHeight = ReadInteger(strind, &nextCharacter);
  292.     if (strind == nextCharacter)
  293.       return (0);
  294.     strind = nextCharacter;
  295.     mask |= HeightValue;
  296.   }
  297.  
  298.   if ((*strind == '+') || (*strind == '-')) {
  299.     if (*strind == '-') {
  300.       strind++;
  301.       tempX = -ReadInteger(strind, &nextCharacter);
  302.       if (strind == nextCharacter)
  303.     return (0);
  304.       strind = nextCharacter;
  305.       mask |= XNegative;
  306.  
  307.     } else {
  308.       strind++;
  309.       tempX = ReadInteger(strind, &nextCharacter);
  310.       if (strind == nextCharacter)
  311.     return(0);
  312.       strind = nextCharacter;
  313.       }
  314.     mask |= XValue;
  315.     if ((*strind == '+') || (*strind == '-')) {
  316.       if (*strind == '-') {
  317.     strind++;
  318.     tempY = -ReadInteger(strind, &nextCharacter);
  319.     if (strind == nextCharacter)
  320.       return(0);
  321.     strind = nextCharacter;
  322.     mask |= YNegative;
  323.  
  324.       } else {
  325.     strind++;
  326.     tempY = ReadInteger(strind, &nextCharacter);
  327.     if (strind == nextCharacter)
  328.       return(0);
  329.     strind = nextCharacter;
  330.       }
  331.       mask |= YValue;
  332.     }
  333.   }
  334.     
  335.   /* If strind isn't at the end of the string the it's an invalid
  336.      geometry specification. */
  337.  
  338.   if (*strind != '\0') return (0);
  339.  
  340.   if (mask & XValue)
  341.     *x = tempX;
  342.   if (mask & YValue)
  343.     *y = tempY;
  344.   if (mask & WidthValue)
  345.     *width = tempWidth;
  346.   if (mask & HeightValue)
  347.     *height = tempHeight;
  348.   return (mask);
  349. }
  350.  
  351. #endif // ifdef WIN32
  352.  
  353. //
  354. // End of "$Id: Fl_arg.cxx,v 1.5 1999/01/07 19:17:31 mike Exp $".
  355. //
  356.